<?php

namespace App\Models;

use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Symfony\Component\VarDumper\Cloner\Data;

/**
 * 积分商城商品兑换记录模型
 * Class GoodsOrder
 * @package app\common\model
 */
class GoodsOrder extends BaseModel
{

    use HasFactory;

    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'change_time';

    protected $table = 'goods_order';

    /**
     * 关联商品数据
     */
    public function conGoods()
    {
        return $this->hasOne(Goods::class, 'id', 'goods_id');
    }

    /**关联用户信息 */
    public function conUser()
    {
        return $this->hasOne(UserInfo::class, 'id', 'user_id');
    }

    /**关联用户地址 */
    public function conAddress()
    {
        return $this->hasOne(GoodsOrderAddress::class, 'order_id', 'id');
    }


    /**
     * 把已过期的订单，表为已过期状态
     */
    public static function checkOrderStatus()
    {
        $res = self::from('goods_order as o')->select('o.id','o.goods_id', 'g.pick_end_time')
            ->join('goods as g', 'g.id', '=', 'o.goods_id')
            // ->whereRaw('status = 1 || status = 3')
            ->whereRaw('status', 1)
            ->where('pick_end_time', '<', date('Y-m-d H:i:s'))
            ->get()
            ->toArray();
        foreach ($res as $key => $val) {
            self::where('id', $val['id'])->update(['status' => 5, 'change_time' => $val['pick_end_time']]);

            //减少兑换数量
            Goods::where('id', $val['goods_id'])->decrement('has_number');
        }
    }

    /**
     * 获取未支付的订单，判断是否过期，修改状态
     */
    public static function checkNoPayOrder()
    {
        $res = self::where('is_pay', 1)->whereNotNull('price')->get();
        foreach ($res as $key => $val) {
            $change_time = date('Y-m-d H:i:s', strtotime("+30 minute", strtotime($val['create_time'])));
            if ($change_time <= date('Y-m-d H:i:s')) {
                self::where('id', $val['id'])->update([
                    'is_pay' => 4,
                    'change_time' => $change_time,
                ]);

                // //用户积分操作  与 系统消息
                // $commonObj = New \app\common\controller\Common();
                // $system_id = $commonObj->systemAdd("积分商品订单过期",$val['user_id'],19, $val['id'],'积分商品订单过期，返还兑换商品扣除的 '.$val['score'].' 积分');

                // $scoreRuleObj = new \app\common\controller\ScoreRule();
                // $scoreRuleObj->scoreGoodReturn($val['score'], $val['account_id'], '积分商品订单过期', '积分商品订单过期' , $system_id);//添加积分消息

                //减少兑换数量
                Goods::where('id', $val['goods_id'])->decrement('has_number');
            }
        }
    }

    /**
     * 获取我的商品个数
     * @param user_id
     */
    public function getMyGoodsNumber($user_id)
    {
        $res = $this->where('user_id', $user_id)->groupBy('goods_id')->pluck('id');
        return count($res);
    }




    /**
     * 商品兑换记录
     * @param page int 当前页
     * @param limit int 分页大小
     * @param send_way int 兑换方式(1 自提 2 邮递  3、2者都可以) 
     * @param start_time datetime 创建时间范围搜索(开始) 
     * @param end_time datetime 创建时间范围搜索(结束) 
     * @param type_id int 商品类型id
     * @param status int 订单状态 1 待领取  2已取走（自提） 3待发货  4已发货 （邮递）  5 已过期   6 已取消 
     * @param keywords string 搜索关键词
     * @param keywords_type int 搜索关键词类型 1 订单号  2 商品名   3 姓名  4 读者证号  5 兑换码
     */
    public function lists($keywords, $keywords_type, $type_id, $status, $send_way, $start_time, $end_time, $limit = 10)
    {
        $res = $this->from('goods_order as o')
            ->select(
                'o.id',
                'o.order_number',
                'o.tracking_number',
                'o.take_time',
                'o.status',
                'o.create_time',
                'o.refund_number',
                'o.refund_time',
                'o.refund_remark',
                'g.id as goods_id',
                'g.img',
                'g.name',
                'g.start_time',
                'g.end_time',
                'g.pick_end_time',
                'status',
                'is_pay',
                'o.cancel_end_time',
                'o.redeem_code',
                'o.score',
                'o.price',
                't.type_name',
                'o.send_way',
                'l.account'
            )
            ->join('goods as g', 'g.id', '=', 'o.goods_id')
            ->join('goods_type as t', 't.id', '=', 'g.type_id')
            ->leftJoin('user_account_lib as l', 'l.id', '=', 'o.account_id')
            ->where(function ($query) use ($keywords_type, $keywords) {
                if ($keywords) {
                    if ($keywords_type == '1') {
                        $query->where('o.order_number', 'like', "%$keywords%");
                    } else if ($keywords_type == '2') {
                        $query->where('g.name', 'like', "%$keywords%");
                    } else if ($keywords_type == '3') {
                        $query->where('l.username', 'like', "%$keywords%");
                    } else if ($keywords_type == '4') {
                        $query->where('l.account', 'like', "%$keywords%");
                    } else if ($keywords_type == '5') {
                        $query->where('o.redeem_code', 'like', "%$keywords%");
                    } else {
                        $query->where('o.order_number', 'like', "%$keywords%")
                            ->orWhere('g.name', 'like', "%$keywords%")
                            ->orWhere('l.username', 'like', "%$keywords%")
                            ->orWhere('l.account', 'like', "%$keywords%")
                            ->orWhere('o.redeem_code', 'like', "%$keywords%");
                    }
                }
            })->where(function ($query) use ($type_id, $status, $send_way, $start_time, $end_time) {
                if ($type_id) {
                    $query->where('g.type_id', $type_id);
                }
                if ($status) {
                    $query->where('o.status', $status);
                }
                if ($send_way) {
                    $query->where('o.send_way', $send_way);
                }
                if ($start_time && $end_time) {
                    $query->whereBetween('o.create_time', [$start_time, $end_time]);
                }
            })
            ->where('is_pay', 2)
            ->orderByDesc('o.create_time')
            ->paginate($limit)
            ->toArray();

        $orderAddressObj = new GoodsOrderAddress();
        $pick_address = GoodsAddress::select('province', 'city', 'district', 'street', 'address', 'tel', 'contacts')->first();
        foreach ($res['data'] as $key => $val) {
            //获取状态
            $res['data'][$key]['status'] = $this->convertStatus($val['status'], $val['is_pay']);
            if ($val['send_way'] == 2) {
                //获取订单地址
                $res['data'][$key]['address_info'] = $orderAddressObj->where('order_id', $val['id'])->first();
            } else {
                //获取邮递地址
                $res['data'][$key]['pick_address'] = $pick_address;
            }
        }
        return $res;
    }
    /**
     * 领取商品
     * @param id 兑换记录id
     */
    public function fetchGoods($id)
    {
        $res = $this->where('id', $id)->where('is_pay', 2)->first();
        if (empty($res)) {
            throw new Exception('订单异常，领取失败');
        }
        if ($res->status != 1) {
            throw new Exception('订单状态异常');
        }
        if ($res->send_way != 1) {
            throw new Exception('此订单不支付自提');
        }
        $res->status = 2;
        $res->take_time = date('Y-m-d H:i:s');
        $res->take_manage_id = request()->manage_id;
        $res->save();
        return $res;
    }


    /**
     * 确认发货
     * @param id int 兑换记录id
     * @param tracking_number string 快递运单号  
     */
    public function sendGoods($id, $tracking_number)
    {

        $res = $this->where('id', $id)->where('is_pay', 2)->first();

        if ($res->status != 3) {
            throw new Exception('订单状态异常');
        }
        if ($res->send_way != 2) {
            throw new Exception('此订单不支付自提');
        }
        $res->tracking_number = $tracking_number;
        $res->take_time = date('Y-m-d H:i:s');
        $res->take_manage_id = request()->manage_id;
        $res->status = 4;
        $res->save();
        return $res;
    }


    /**
     * 获取某个商品的兑换次数
     * @param user_id
     * @param goods_id
     */
    public function getConversionNumber($user_id, $goods_id)
    {
        return $this->where(function ($query) use ($user_id, $goods_id) {
            if ($user_id) {
                $query->where('user_id', $user_id);
            }
            if ($goods_id) {
                $query->where('goods_id', $goods_id);
            }
        })->whereIn('status', [1, 2, 3, 4])
            ->whereIn('is_pay', [1, 2])
            ->count();
    }


    /**
     * 转换支付状态
     * 状态 1 待领取  2已取走（自提） 3待发货  4已发货 （邮递）  5 已过期   6 已取消   7 未支付 8 支付异常， 9 订单已失效 10 .已退款
     */
    public function convertStatus($status, $is_pay)
    {

        if ($is_pay == 1) {
            $status = 7; //1 未支付 2 已支付    3支付异常， 4 订单已失效 5 .已退款
        } elseif ($is_pay == 3) {
            $status = 8; //1 未支付 2 已支付    3支付异常， 4 订单已失效 5 .已退款
        } elseif ($is_pay == 4) {
            $status = 9; //1 未支付 2 已支付    3支付异常， 4 订单已失效 5 .已退款
        } elseif ($is_pay == 5) {
            $status = 10; //1 未支付 2 已支付    3支付异常， 4 订单已失效 5 .已退款
        }
        return $status;
    }


    /**
     * 转化订单状态
     */
    function getStatusName($index)
    {
        switch ($index) {
            case 1:
                return '待领取';
                break;
            case 2:
                return '已取走(自提)';
                break;
            case 3:
                return '待发货';
                break;
            case 4:
                return '已发货(邮递)';
                break;
            case 5:
                return '已过期';
                break;
            case 6:
                return '已取消';
                break;
            case 7:
                return '未支付';
                break;
            case 8:
                return '支付异常';
                break;
            case 9:
                return '订单已失效';
                break;
            case 10:
                return '已退款';
                break;
            default:
                return '未知状态';
                break;
        }
    }

    /**
     * 转化发货方式
     */
    function getSendWayName($index)
    {
        switch ($index) {
            case 1:
                return '自提';
                break;
            case 2:
                return '邮递';
                break;
            case 3:
                return '自提、邮递皆可';
                break;
            default:
                return '未知状态';
                break;
        }
    }
}
